package controllers

import (
	"covalence/models"
	"covalence/util"
	//"encoding/json"
	"fmt"
	"github.com/astaxie/beego"
	"github.com/astaxie/beego/orm"
	//"os"
	//"strconv"
	"strings"
	//"time"
)

type TargetController struct {
	baseController
}

func (this *TargetController) ShowHTML() {
	this.TplNames = "TargetBrowse.html"
}

func (this *TargetController) ShowResultsHTML() {
	this.TplNames = "TrgSearchResults.html"
}

/*
** Ligands Browser for one of multiple pages
** Display basic informaiton of ligand
 */
func (this *TargetController) Browse() {

	fmt.Println("Target browse")
	/*
	**	get limited ligands info from ligand table
	 */
	start, _ := this.GetInt64("startTrg")
	limit, _ := this.GetInt64("perPageTrgCount")
	fmt.Println(start)
	fmt.Println(limit)
	if this.dbBasicInfo.TargetsConut < (start + limit) {
		limit = this.dbBasicInfo.TargetsConut - start
	}

	var targets []models.Target
	qs := orm.NewOrm().QueryTable("target")
	_, err := qs.Limit(limit, start).All(&targets)
	if err != nil {
		this.responseMsg.ErrorMsg("", nil)
		this.Data["json"] = this.responseMsg
		this.ServeJson()
		return
	}

	/*
	**	get basic info of target
	**  step 1: get Residue from relation table
	 */
	var basicTargets []models.TargetBasicInfo
	for _, target := range targets {
		var basicTrg models.TargetBasicInfo
		basicTrg.TrgId = target.TrgId
		basicTrg.UniprotKb = target.UniprotKb
		basicTrg.TrgName = target.TrgName
		basicTrg.ShortName = target.ShortName
		basicTrg.Organism = target.Organism
		basicTrg.Gene = target.Gene
		basicTrg.HgncId = target.HgncId
		basicTrg.TarImg = target.TarImg
		basicTrg.RelationId = target.RelationId
		basicTrg.Classification = target.Classification
		basicTrg.MolsZipfile = target.MolsZipfile

		var relations []models.Relation
		qs := orm.NewOrm().QueryTable("relation")
		_, err := qs.Filter("TrgId", target.TrgId).All(&relations)
		if err != nil {
			continue
		}
		for _, rel := range relations {
			residues := strings.Split(strings.TrimSpace(rel.Residue), "$")
			for _, residue := range residues {
				if !util.InArrayString(basicTrg.Residue, residue) {
					basicTrg.Residue = append(basicTrg.Residue, residue)
				}
			}
		}
		basicTargets = append(basicTargets, basicTrg)
	}

	/*
	** send back basic data of target
	 */
	data := make(map[string]interface{})
	data["totalTargetsCount"] = this.dbBasicInfo.TargetsConut
	data["targets"] = basicTargets

	this.responseMsg.SuccessMsg("", data)
	this.Data["json"] = this.responseMsg
	this.ServeJson()
	//this.TplNames = "chemdb_browse.html"
}

/*
** Display details informaiton of one target
 */
func (this *TargetController) GetDetailsOfTarget() {

	fmt.Println("Target details")

	trgID := this.GetString("trgID")
	fmt.Println(trgID)

	var detailsInfo models.TargetDetailsInfo
	detailsInfo.Target.TrgId = trgID
	err := detailsInfo.Target.Read("TrgId")
	if err != nil {
		this.responseMsg.ErrorMsg("", nil)
		this.Data["json"] = this.responseMsg
		this.ServeJson()
		return
	}

	/*
	**	get details info of target
	**  step 1: get data from targetDomain table
	**  step 2: get data from relation table
	**  step 3: get data from reference table
	 */
	qs := orm.NewOrm().QueryTable("targetdomain")
	_, err = qs.Filter("UniprotKb", detailsInfo.Target.UniprotKb).All(&detailsInfo.TargetDomains)

	qs = orm.NewOrm().QueryTable("relation")
	_, err = qs.Filter("TrgId", trgID).All(&detailsInfo.Relations)

	qs = orm.NewOrm().QueryTable("reference")
	_, err = qs.Filter("TrgId", trgID).All(&detailsInfo.References)

	/*
	** send basic data of ligand back
	 */
	data := make(map[string]interface{})
	data["targetDetails"] = detailsInfo

	this.responseMsg.SuccessMsg("", data)
	this.Data["json"] = this.responseMsg
	this.ServeJson()
	//this.TplNames = "chemdb_browse.html"
}

func (this *TargetController) Query() {

	fmt.Println("Target Query")
	TargetName := strings.TrimSpace(this.GetString("TargetName"))
	var targets []*models.Target
	cond := orm.NewCondition().And("TrgName__icontains", TargetName).Or("ShortName__icontains", TargetName)
	qs := orm.NewOrm().QueryTable("target")
	qs.SetCond(cond).All(&targets)

	/*
	**	get basic info of target
	**  step 1: get Residue from relation table
	 */
	var basicTargets []models.TargetBasicInfo
	for _, target := range targets {
		var basicTrg models.TargetBasicInfo
		basicTrg.TrgId = target.TrgId
		basicTrg.UniprotKb = target.UniprotKb
		basicTrg.TrgName = target.TrgName
		basicTrg.ShortName = target.ShortName
		basicTrg.Organism = target.Organism
		basicTrg.Gene = target.Gene
		basicTrg.HgncId = target.HgncId
		basicTrg.TarImg = target.TarImg
		basicTrg.RelationId = target.RelationId
		basicTrg.Classification = target.Classification
		basicTrg.MolsZipfile = target.MolsZipfile

		var relations []models.Relation
		qs := orm.NewOrm().QueryTable("relation")
		_, err := qs.Filter("TrgId", target.TrgId).All(&relations)
		if err != nil {
			continue
		}
		for _, rel := range relations {
			residues := strings.Split(strings.TrimSpace(rel.Residue), "$")
			for _, residue := range residues {
				if !util.InArrayString(basicTrg.Residue, residue) {
					basicTrg.Residue = append(basicTrg.Residue, residue)
				}
			}
		}
		basicTargets = append(basicTargets, basicTrg)
	}

	/*
	** send back basic data of target
	 */
	data := make(map[string]interface{})
	data["totalTargetsCount"] = len(targets)
	data["targets"] = basicTargets

	this.responseMsg.SuccessMsg("", data)
	this.Data["json"] = this.responseMsg
	this.ServeJson()
}

func (this *TargetController) GetPdbFile() {

	fmt.Println("Target details")

	pdbCodes := strings.Split(strings.TrimSpace(this.GetString("PdbCodes")), ";")
	pdfFilePath := beego.AppConfig.String("pdbFilePath")
	data := make(map[string]interface{})
	var pdbs []*models.PDBInfo
	for _, pdbCode := range pdbCodes {
		var pdb models.PDBInfo
		err, pdbStr := util.GetPdbStrFromCode(pdbCode, pdfFilePath)
		if err != nil {
			continue
		}
		pdb.Code = pdbCode
		pdb.Data = pdbStr
		pdbs = append(pdbs, &pdb)
	}

	if len(pdbs) == 0 {
		this.responseMsg.ErrorMsg("", nil)
		this.Data["json"] = this.responseMsg
		this.ServeJson()
		return
	}

	data["pdbs"] = pdbs
	this.responseMsg.SuccessMsg("", data)
	this.Data["json"] = this.responseMsg
	this.ServeJson()
}
